/******************************************************************************
	Cobalt - utility libraries for building XNA games
	Copyright (C) 2008 Philip Djonov

	This program is free software; you can redistribute it and/or modify it
	under the terms of the GNU General Public License as published by the Free
	Software Foundation; either version 2 of the License, or (at your option)
	any later version.

	This program is distributed in the hope that it will be useful, but
	WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
	or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
	for more details.

	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the
	
		Free Software Foundation, Inc.
		51 Franklin Street, Fifth Floor
		Boston, MA  02110-1301, USA.
******************************************************************************/

using System;
using System.Collections;
using System.Runtime.InteropServices;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Cobalt.Framework.Graphics
{
	[StructLayout( LayoutKind.Explicit, Size = 20 )]
	public struct PointSpriteVertex
	{
		[FieldOffset( 0 )]
		public Vector3 Position;
		[FieldOffset( 12 )]
		public float Size;
		[FieldOffset( 16 )]
		public Color Color;

		public const int Stride = 20;

		private static readonly VertexElement[] declarationElements = new VertexElement[]
			{
				new VertexElement( 0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0 ),
				new VertexElement( 0, 12, VertexElementFormat.Single, VertexElementMethod.Default, VertexElementUsage.PointSize, 0 ),
				new VertexElement( 0, 16, VertexElementFormat.Color, VertexElementMethod.Default, VertexElementUsage.Color, 0 ),
			};
		public static VertexElement[] DeclarationElements
		{
			get { return declarationElements; }
		}
	}

	public sealed class PointSpriteRenderer : UserGeometryRenderer<PointSpriteVertex>
	{
		public PointSpriteRenderer( GraphicsDevice device )
			: base( device, PointSpriteVertex.DeclarationElements )
		{
		}

		public StaticGeometryBatch<PointSpriteVertex> CreateStaticBatch( PointSpriteVertex[] vertices )
		{
			if( vertices == null )
				throw new ArgumentNullException();
			if( vertices.Length == 0 )
				throw new ArgumentException();

			return CreateStaticBatch( PrimitiveType.PointList, vertices );
		}

		public DynamicGeometryBatch<PointSpriteVertex> CreateDynamicBatch( int capacity )
		{
			if( capacity < 0 )
				throw new ArgumentOutOfRangeException();

			return CreateDynamicBatch( PrimitiveType.PointList, capacity );
		}

		protected internal override void DrawSurfaces( DrawRecord[] surfaces, int index, int count, ShadingContext context, IPrerenderHandler prerenderHandler )
		{
			Device.RenderState.PointSpriteEnable = true;

			base.DrawSurfaces( surfaces, index, count, context, prerenderHandler );

			Device.RenderState.PointSpriteEnable = false;
		}
	}
}